/*
 * Copyright Hundsun Technologies Inc. All Rights Reserved.
 */

package protocol

import (
	"fmt"

	"github.com/libp2p/go-libp2p-core/host"
	"github.com/libp2p/go-libp2p-core/network"
	"github.com/libp2p/go-libp2p-core/protocol"
	"hundsun.com/hsl/hschain/p2p/impl/dht/node"
	"hundsun.com/hsl/hschain/store/mq"
)

// RegisterStreamHandler registers stream handler
func RegisterStreamHandler(h host.Host, p protocol.ID, handler network.StreamHandler) {
	if handler == nil {
		panic(fmt.Sprintf("addEventHandler, handler is nil, protocol=%s", p))
	}
	h.SetStreamHandler(p /*node.HandlerWithClose(handler)*/, handler)
}

//Initer Initializer is a initial function which any protocol should have.
type Initer func(env *P2PEnv)

var (
	protocolIniters []Initer
)

//RegisterProtocolIniter register the ProtocolIniter function.
func RegisterProtocolIniter(initer Initer) {
	protocolIniters = append(protocolIniters, initer)
}

//InitProtocols initials all protocols.
func InitProtocols(env *P2PEnv) {
	for _, initializer := range protocolIniters {
		initializer(env)
	}
}

// EventHandler handles event
type EventHandler func(*mq.Message)

var (
	eventHandlers = make(map[int64]EventHandler)
)

// RegisterEventHandler registers a handler with an event ID.
func RegisterEventHandler(eventID int64, handler EventHandler) {
	if handler == nil {
		panic(fmt.Sprintf("addEventHandler, handler is nil, id=%d", eventID))
	}
	if _, dup := eventHandlers[eventID]; dup {
		panic(fmt.Sprintf("addEventHandler, duplicate handler, id=%d, len=%d", eventID, len(eventHandlers)))
	}
	eventHandlers[eventID] = node.EventHandlerWithRecover(handler)
}

// GetEventHandler gets event handler by event ID.
func GetEventHandler(eventID int64) EventHandler {
	return eventHandlers[eventID]
}
